﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;
//using System.Windows.Forms.Timer;

//port 8000 : banker game data
//port 8001 : banker send image
//port 8002 : banker get image
//port 8003 : investor game data
//port 8004 : investor send image
//port 8005 : investor get image

namespace ReadFilesFromDirectory
{
    public partial class ServerMainForm : Form
    {
        #region tryingtohavequestionairre
            private int investorConnectionCode = 1;
            private int trusteeConnectionCode  = 2;
            private Boolean clearedToSendImage = false;
        #endregion tryingtohavequestionairre

        private int FINALROUNDNUMBER = 10;
        private const int imageSize1 = 16384;  /*341504;*/ //800054;
        private const int imageSize2 = 8192;   /*307254;*/ //846848;
        private TextWriter tw;
        private System.Windows.Forms.Timer MyTimer1, MyTimer2, MyTimer3;
     
        private int investorMoney;

        #region credentials
            private Credentials credentials;
            private string trusteeUserName, trusteePasswd;
            private string investorUserName, investorPasswd;
            private int investorTotal, investorGotMoney, investorSentMoney;
        #endregion crediantials

        #region delegateInvestorMoney
            public delegate void setInvestorTotal(int sentMoney, int gotMoney, int totalMoney);
            private void updateInvestorSentMoney(int sentMoney, int gotMoney, int totalMoney)
            {
                this.Invoke(new setInvestorTotal(updateInvTotal), new object[] {sentMoney, gotMoney, totalMoney});
            }
            private void updateInvTotal(int sentMoney, int gotMoney, int totalMoney)
            {
                if (sentMoney != -1)  { investorSentMoney = sentMoney; }
                if (gotMoney != -1)   { investorGotMoney = gotMoney; }
                if (totalMoney != -1) { investorTotal = totalMoney; }
            }

            public delegate int getInvestorInvestedMoney();
            private int retrieveInvestorInvestedMoney()
            {
                return (int)this.Invoke(new getInvestorInvestedMoney(getInvInvestment));
            }
            private int getInvInvestment()
            {
                return investorSentMoney;
            }
        #endregion delegateInvestorMoney

        #region formOperations
            public ServerMainForm()
            {
                InitializeComponent();
                lookAndFeel();
            }
            private void lookAndFeel()
            {
                rect_investorTotalMoney.SetBounds(66, 177, 40, 3);
                rect_investorGave.SetBounds(168, 177, 40, 3);
                rect_investorKept.SetBounds(263, 177, 40, 3);

                rect_trusteeTotalMoney.SetBounds(66, 177, 40, 3);
                rect_trusteeGave.SetBounds(168, 177, 40, 3);
                rect_trusteeKept.SetBounds(263, 177, 40, 3);

                label_trusteeTotalMoney.Location = new Point(73, 32);
                label_trusteeRepayed.Location = new Point(170, 32);
                label_trusteeGot.Location = new Point(269, 32);

                label_investorTotalMoney.Location = new Point(72, 32);
                label_investorInvested.Location = new Point(174, 32);
                label_investorGot.Location = new Point(271, 32);

                label_invtotal.Location = new Point(73, 206);
                label_invmoney.Location = new Point(71, 225);
                label_invinvested.Location = new Point(164, 221);
                label_invGot.Location = new Point(275, 221);

                label_trusteeTotal.Location = new Point(73, 209);
                label_trusteeMoney.Location = new Point(71, 225);
                label_trusteeKept.Location = new Point(170, 213);
                label_trusteeRepay.Location = new Point(249, 213);
            }
            private int maximum(int x, int y, int z)
            {
                int max = x;
                if (y > max) { return y; }
                if (z > max) { return z; }
                return max;
            }           
            private void videoStreamingToolStripMenuItem_Click(object sender, EventArgs e)
            {
                AdminDirectoryUtility adminUtilityForm = new AdminDirectoryUtility();
                adminUtilityForm.Owner = this;
                adminUtilityForm.Show();
                this.Enabled = false;
            }
            public void setCredentials(string _trusteeUserName, string _trusteePasswd, string _investorUserName, string _investorPasswd)
            {
                trusteeUserName     = _trusteeUserName;
                trusteePasswd       = _trusteePasswd;
                investorUserName    = _investorUserName;
                investorPasswd      = _investorPasswd;
            }

            public delegate void setTheRoundNumber(int _count);
            private void setRoundNumber(int _count)
            {
                if (textBox_roundNumber.InvokeRequired)
                {
                    setTheRoundNumber del = new setTheRoundNumber(setRoundNumber);
                    textBox_roundNumber.Invoke(del, new object[] { _count });
                    updateInfoTextFile("Round Number " + _count.ToString());
                }
                else
                {
                    textBox_roundNumber.Text = _count.ToString();
                }
            }
            private void startSession_Click(object sender, EventArgs e)
            {
                NewSession newSession = new NewSession();
                newSession.Owner = this;
                newSession.FormBorderStyle = FormBorderStyle.FixedDialog;
                newSession.MaximizeBox = false;
                newSession.MinimizeBox = false;
                newSession.StartPosition = FormStartPosition.CenterScreen;


                button_startsession.Enabled = false;
                startSessionToolStripMenu.Enabled = false;
                button_startServer.Enabled = true;
                startServerToolStripMenuItem.Enabled = true;

                this.Enabled = false; ;
                newSession.Show();
            }
            private void exitForm_Click(object sender, EventArgs e){ }

            private void stopTheSessionToolStripMenuItem_Click(object sender, EventArgs e)
            {
                startSessionToolStripMenu.Enabled = true;
                button_startsession.Enabled = true;
                button_stopServer.Enabled = false;
                stopTheSessionToolStripMenuItem.Enabled = false;

                // stop the session here
                CloseSockets();

                //after server stops
                label_serverinformation.Text = "Server is offline";

                this.Dispose();
            }
            private void button_startServer_Click(object sender, EventArgs e)
            {
                credentials = Credentials.Instance;

                setCredentials(credentials.TrusteeUserName, credentials.TrusteePasswd, credentials.InvestorUserName, credentials.InvestorPasswd);
                setRoundNumber(1);

                startServerToolStripMenuItem.Enabled = false;
                button_startServer.Enabled = false;
                button_stopServer.Enabled = true;
                stopTheSessionToolStripMenuItem.Enabled = true;
                startServer();
                label_serverinformation.Text = "Server is online";

                //open a file that stores information of the game
                tw = new StreamWriter(credentials.FolderName + "\\info.txt");
            }
        #endregion formOperations

        #region delegates
        #region delegateSetTrusteeGraph
            public delegate void updateTrusteeGraph(int totalMoney, int sentMoney, int gotMoney);
            private void updateGUITrustee(int totalMoney, int sentMoney, int gotMoney)
            {
                this.Invoke(new updateInvestorGraph(setTrusteeGraph), totalMoney, sentMoney, gotMoney);
            }
            private void setTrusteeGraph(int totalMoney, int gaveMoney, int gotMoney)
            {
                int max = maximum(totalMoney, gaveMoney, gotMoney);
                int height;

                if (totalMoney != -1)
                {
                    height = (int)(((float)totalMoney / (float)max) * 120);
                    rect_trusteeTotalMoney.SetBounds(66, 180 - height, 40, height); //total money $20 66, 180 - height, 40, height
                    label_trusteeTotalMoney.Text = " " + totalMoney.ToString();
                }

                if (gaveMoney != -1)
                {
                    height = (int)(((float)gaveMoney / (float)max) * 120);
                    rect_trusteeGave.SetBounds(168, 180 - height, 40, height);
                    label_trusteeRepayed.Text = " " + gaveMoney.ToString();
                }

                if (gotMoney != -1)
                {
                    height = (int)(((float)gotMoney / (float)max) * 120);
                    rect_trusteeKept.SetBounds(263, 180 - height, 40, height);
                    label_trusteeGot.Text = " " + gotMoney.ToString();
                }
            }
        #endregion delegateSetTrusteeGraph

        #region delegateSetInvestorGraph
            public delegate void updateInvestorGraph(int totalMoney, int sentMoney, int gotMoney);
            private void updateGUIInvestor(int totalMoney, int sentMoney, int gotMoney)
            {
                this.Invoke(new updateInvestorGraph(setInvestorGraph), totalMoney, sentMoney, gotMoney);
            }
            private void setInvestorGraph(int totalMoney, int sentMoney, int gotMoney)
            {
                int max = maximum(totalMoney, sentMoney, gotMoney);
                int height;

                if (totalMoney != -1)
                {
                    height = (int)(((float)totalMoney / (float)max) * 120);
                    rect_investorTotalMoney.SetBounds(66, 180 - height, 40, height);
                    label_investorTotalMoney.Text = " "+totalMoney.ToString();
                }

                if (sentMoney != -1)
                {
                    height = (int)(((float)sentMoney / (float)max) * 120);
                    rect_investorGave.SetBounds(168, 180 - height, 40, height);
                    label_investorInvested.Text = " " + sentMoney.ToString();
                }

                if (gotMoney != -1)
                {
                    height = (int)(((float)gotMoney / (float)max) * 120);
                    rect_investorKept.SetBounds(263, 180 - height, 40, height);
                    label_investorGot.Text = " "+gotMoney.ToString();
                }
            }
        #endregion delegateSetInvestorGraph

        #region profitlossdelegate
            public delegate void updateInfoTextFileDelegate(String data);
            private void updateInfoTextFile(String data)
            {
                this.Invoke(new updateInfoTextFileDelegate(updateInfo), data);
            }
            private void updateInfo(String data)
            {
                tw.WriteLine(data);
            }

            public delegate void updateProfitLossLables(int investedMoney, int RepaidMoney);
            private void updateProfitLossStats(int investedMoney, int RepaidMoney)
            {
                this.Invoke(new updateProfitLossLables(updateStatsLabels), investedMoney, RepaidMoney);
            }
            private void updateStatsLabels(int investedMoney, int RepaidMoney)
            {
                textBox_investorRoundProfit.Text = (RepaidMoney - investedMoney).ToString();
                textBox_investorTotalProfit.Text = (int.Parse(textBox_investorTotalProfit.Text) + (20 + RepaidMoney - investedMoney)).ToString();
                
                int moneyKeptByTrustee = 3*investedMoney - RepaidMoney;

                textBox_trusteeRoundProfit.Text = (moneyKeptByTrustee).ToString();
                textBox_trusteeTotalProfit.Text = (int.Parse(textBox_trusteeTotalProfit.Text) + (moneyKeptByTrustee)).ToString();
            }
            #endregion profitlossdelegate

        #endregion delegates
        //get the IP address of the machine where the server is running
        private String GetIP()
        {
            String myHostName = Dns.GetHostName();

            // Find host by name
            IPHostEntry myiphost = Dns.GetHostEntry(myHostName);

            String ipstring = "";
            foreach (IPAddress myipadd in myiphost.AddressList)
            {
                if (myipadd.AddressFamily == AddressFamily.InterNetwork)
                {
                    return myipadd.ToString();

                }
            }
            return ipstring;
        }

        #region socket_operations
            #region bankerGameData
                public AsyncCallback pfnWorkerCallBackBankerGameData;
                private Socket m_mainGameSocketBanker;
                private Socket m_workerGameSocketBanker;
                private void StartListeningTrusteeGame()
                {
                    try
                    {
                        string portStr ="8000";
                        int port_banker = System.Convert.ToInt32(portStr);

                        // Create the listening socket...
                        m_mainGameSocketBanker = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        IPEndPoint ip_gamebanker = new IPEndPoint(IPAddress.Parse(GetIP()), port_banker);

                        // Bind to local IP Address...
                        m_mainGameSocketBanker.Bind(ip_gamebanker);

                        // Start listening...
                        m_mainGameSocketBanker.Listen(4);

                        // Create the call back for any client connections...
                        m_mainGameSocketBanker.BeginAccept(new AsyncCallback(OnBankerGameConnect), null);
                    }
                    catch (Exception e) { throw e; }
                }
                public void OnBankerGameConnect(IAsyncResult asyn)
                {
                    try
                    {
                        m_workerGameSocketBanker = m_mainGameSocketBanker.EndAccept(asyn);
                        WaitForBankerGameData();
                        m_mainGameSocketBanker.BeginAccept(new AsyncCallback(OnBankerGameConnect), null);
                        setTextBankerStatus("Trustee is currently connected");
                    }
                    catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n"); }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                public void WaitForBankerGameData()
                {
                    try
                    {
                        if (pfnWorkerCallBackBankerGameData == null)
                        {
                            pfnWorkerCallBackBankerGameData = new AsyncCallback(OnBankerGameDataReceived);
                        }
                        SocketPacket theSocPkt = new SocketPacket(m_workerGameSocketBanker);

                        m_workerGameSocketBanker.BeginReceive(theSocPkt.gameBuffer, 0,
                            theSocPkt.gameBuffer.Length, SocketFlags.None,
                            pfnWorkerCallBackBankerGameData, theSocPkt);
                    }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                public void OnBankerGameDataReceived(IAsyncResult asyn)
                {
                    SocketPacket socketData = (SocketPacket)asyn.AsyncState;
                    try
                    {
                        int val = int.Parse(System.Text.Encoding.UTF8.GetString(socketData.gameBuffer));
                        intiateSequence((3*investorMoney - val), val, 2);
                        SendGameMessageToInvestor(socketData);
                        setTextGameCommentry("Trustee has repayed " + val.ToString() + " points back to Investor");


                        updateInfoTextFile("Trustee repayed : " + val.ToString() + " points");

                        WaitForBankerGameData();
                    }
                    #region catchBlock
                        catch (ObjectDisposedException)
                        {
                            System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Banker Socket has been closed\n");
                        }
                        catch (SocketException se)
                        {
                            if (se.ErrorCode == 10054) // Error code for Connection reset by peer
                            {
                                System.Diagnostics.Debugger.Log(0, "1", "Banker Disconnected");

                                // Remove the reference to the worker socket of the closed client
                                // so that this object will get garbage collected
                                m_workerSocketBankerSendImage = null;

                                setTextBankerStatus("Banker is currently not connected");
                            }
                            else
                            {
                                System.Diagnostics.Debugger.Log(0, "1", se.Message);
                            }
                        }
                        catch (Exception e)
                        {
                            System.Diagnostics.Debugger.Log(0, "1", "\nexception caught");
                            System.Diagnostics.Debugger.Log(0, "1", e.Message);
                            System.Diagnostics.Debugger.Log(0, "1", e.Source);
                            System.Diagnostics.Debugger.Log(0, "1", e.StackTrace);
                        }
                    #endregion catchBlock
                }
                private void SendGameMessageToInvestor(SocketPacket socketData)
                {
                    try
                    {
                        if (m_workerGameSocketInvestor != null)
                        {
                            int repaidMoney = int.Parse(System.Text.Encoding.UTF8.GetString(socketData.gameBuffer));

                            int investedMoney = retrieveInvestorInvestedMoney();
                            updateGUIInvestor(20, investedMoney, repaidMoney);
                            updateGUITrustee(3*investedMoney, (3*investedMoney - repaidMoney), repaidMoney);
                            updateProfitLossStats(investedMoney, repaidMoney);

                            m_workerGameSocketInvestor.Send(socketData.gameBuffer);
                        }
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                }
            #endregion bankerGameData
            #region bankerSendImage
                public AsyncCallback pfnWorkerCallBackBankerSendImage;
                private Socket m_mainSocketBankerSendImage;
                private Socket m_workerSocketBankerSendImage;
                private void StartListeningTrusteeSendImage()
                {
                    try
                    {
                        string portStr = "8001"; // GetIP();
                        string ip = GetIP();
                        int port_banker = System.Convert.ToInt32(portStr);

                        // Create the listening socket...
                        m_mainSocketBankerSendImage = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        IPEndPoint ip_banker = new IPEndPoint(IPAddress.Parse(GetIP()), port_banker);

                        // Bind to local IP Address...
                        m_mainSocketBankerSendImage.Bind(ip_banker);
                        m_mainSocketBankerSendImage.Listen(4);
                        m_mainSocketBankerSendImage.BeginAccept(new AsyncCallback(OnBankerSendImageConnect), null);
                    }
                    catch (Exception e) { throw e; }
                }
                public void OnBankerSendImageConnect(IAsyncResult asyn)
                {
                    try
                    {
                        //which returns the reference to a new Socket object
                        m_workerSocketBankerSendImage = m_mainSocketBankerSendImage.EndAccept(asyn);

                        // Let the worker Socket do the further processing for the just connected client
                        WaitForBankerSendImageData();

                        // Since the main Socket is now free, it can go back and wait for other clients who are attempting to connect
                        m_mainSocketBankerSendImage.BeginAccept(new AsyncCallback(OnBankerSendImageConnect), null);

                        setTextBankerStatus("Trustee is currently connected");
                    }
                    catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n"); }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                public void WaitForBankerSendImageData()
                {
                    try
                    {
                        if (pfnWorkerCallBackBankerSendImage == null) { pfnWorkerCallBackBankerSendImage = new AsyncCallback(OnBankerSendImageDataReceived); }
                        SocketPacket theSocPkt = new SocketPacket(m_workerSocketBankerSendImage);
                        m_workerSocketBankerSendImage.BeginReceive(theSocPkt.dataBuffer, 0,theSocPkt.dataBuffer.Length, SocketFlags.None,pfnWorkerCallBackBankerSendImage, theSocPkt);
                    }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                public void OnBankerSendImageDataReceived(IAsyncResult asyn)
                {
                    SocketPacket socketData = (SocketPacket)asyn.AsyncState;
                    try
                    {
                        int iRx = m_workerSocketBankerSendImage.EndReceive(asyn);

                        if (iRx == imageSize1 || iRx == imageSize2)
                        {
                            Image img = byteArrayToImage(socketData.dataBuffer);

                            Image saveimg = cropImage(img);
                            pictureBox_trustee.Image = saveimg;

                            if(clearedToSendImage)
                                SendImageToInvestor(socketData);

                            //saveimg.Save(Credentials.folderName + "\\trustee\\" + trusteeImageCounter + ".png");
                            //trusteeImageCounter++;
                        }

                        WaitForBankerSendImageData();        // Continue the waiting for data on the Socket

                    }
                    #region catchBlock
                    catch (ObjectDisposedException)
                    {
                        System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Banker Socket has been closed\n");
                    }
                    catch (SocketException se)
                    {
                        if (se.ErrorCode == 10054) // Error code for Connection reset by peer
                        {
                            System.Diagnostics.Debugger.Log(0, "1", "Banker Disconnected");

                            // Remove the reference to the worker socket of the closed client
                            // so that this object will get garbage collected
                            m_workerSocketBankerSendImage = null;

                            setTextBankerStatus("Banker is currently not connected");
                        }
                        else
                        {
                            System.Diagnostics.Debugger.Log(0, "1", se.Message);
                        }
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Debugger.Log(0, "1", "\nexception caught");
                        System.Diagnostics.Debugger.Log(0, "1", e.Message);
                        System.Diagnostics.Debugger.Log(0, "1", e.Source);
                        System.Diagnostics.Debugger.Log(0, "1", e.StackTrace);
                    }
                    #endregion catchBlock
                }

                private Image cropImage(Image img)
                {
                    Rectangle cropRect = new Rectangle(0, 0, 400, 400);
                    Bitmap src = img as Bitmap;
                    Bitmap target = new Bitmap(cropRect.Width, cropRect.Height);

                    using(Graphics g = Graphics.FromImage(target))
                    {
                       g.DrawImage(src, new Rectangle(0, 0, target.Width, target.Height), 
                                        cropRect,                        
                                        GraphicsUnit.Pixel);
                    }

                    return target;
                }

                private void SendImageToInvestor(SocketPacket socketData)
                {
                    try
                    {
                        if (m_workerSocketInvestorGetImage != null)
                        {
                            m_workerSocketInvestorGetImage.Send(socketData.dataBuffer);
                        }
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                }         
            #endregion bankerSendImage
            #region bankerGetImage
                public AsyncCallback pfnWorkerCallBackBankerGetImage;
                private Socket m_mainSocketBankerGetImage;
                private Socket m_workerSocketBankerGetImage;
                private void StartListeningTrusteeGetImage()
                {
                    try
                    {
                        string portStr = "8002"; // GetIP();
                        int port_banker = System.Convert.ToInt32(portStr);

                        // Create the listening socket...
                        m_mainSocketBankerGetImage = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        IPEndPoint ip_banker = new IPEndPoint(IPAddress.Parse(GetIP()), port_banker);

                        // Bind to local IP Address...
                        m_mainSocketBankerGetImage.Bind(ip_banker);

                        // Start listening...
                        m_mainSocketBankerGetImage.Listen(4);

                        // Create the call back for any client connections...
                        m_mainSocketBankerGetImage.BeginAccept(new AsyncCallback(OnBankerGetImageConnect), null);
                    }
                    catch (Exception e) { throw; }
                }
                public void OnBankerGetImageConnect(IAsyncResult asyn)
                {
                    try
                    {
                        //which returns the reference to a new Socket object
                         m_workerSocketBankerGetImage = m_mainSocketBankerGetImage.EndAccept(asyn);

                        // Let the worker Socket do the further processing for the just connected client
                        //WaitForBankerGetImageData();

                        // Since the main Socket is now free, it can go back and wait for other clients who are attempting to connect
                        //m_mainSocketBankerGetImage.BeginAccept(new AsyncCallback(OnBankerGetImageConnect), null);

                        setTextBankerStatus("Trustee is currently connected");
                    }
                    catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n"); }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                /*public void WaitForBankerGetImageData()
                {
                    try
                    {
                        if (pfnWorkerCallBackBankerSendImage == null) { pfnWorkerCallBackBankerSendImage = new AsyncCallback(OnBankerGetImageDataReceived); }
                        SocketPacket theSocPkt = new SocketPacket(m_workerSocketBankerGetImage);

                        m_workerSocketBankerGetImage.BeginReceive(theSocPkt.dataBuffer, 0,
                            theSocPkt.gameBuffer.Length, SocketFlags.None,
                            pfnWorkerCallBackBankerGetImage, theSocPkt);
                    }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                public void OnBankerGetImageDataReceived(IAsyncResult asyn)
                {
                    SocketPacket socketData = (SocketPacket)asyn.AsyncState;
                    try
                    {
                        int iRx = m_workerSocketBankerSendImage.EndReceive(asyn);

                        if (iRx == 800054)
                        {
                            // bankerPicture.Image = byteArrayToImage(socketData.dataBuffer);
                            //SendImageToInvestor(socketData);
                        }

                        WaitForBankerGetImageData();        // Continue the waiting for data on the Socket

                    }
                    #region catchBlock
                        catch (ObjectDisposedException)
                        {
                            System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Banker Socket has been closed\n");
                        }
                        catch (SocketException se)
                        {
                            if (se.ErrorCode == 10054) // Error code for Connection reset by peer
                            {
                                System.Diagnostics.Debugger.Log(0, "1", "Banker Disconnected");

                                // Remove the reference to the worker socket of the closed client
                                // so that this object will get garbage collected
                                m_workerSocketBankerSendImage = null;

                                setTextBankerStatus("Banker is currently not connected");
                            }
                            else
                            {
                                System.Diagnostics.Debugger.Log(0, "1", se.Message);
                            }
                        }
                        catch (Exception e)
                        {
                            System.Diagnostics.Debugger.Log(0, "1", "\nexception caught");
                            System.Diagnostics.Debugger.Log(0, "1", e.Message);
                            System.Diagnostics.Debugger.Log(0, "1", e.Source);
                            System.Diagnostics.Debugger.Log(0, "1", e.StackTrace);
                        }
                    #endregion catchBlock
                }
                private void SendImageToInvestor(SocketPacket socketData)
                {
                    try
                    {
                        if (m_workerSocketInvestorSendImage != null)
                        {
                            m_workerSocketInvestorGetImage.Send(socketData.dataBuffer);
                        }
                    }
                    catch (Exception e)
                    {
                        throw;
                    }
                } */
            #endregion bankerGetImage
            #region CredentialSocket
                public AsyncCallback pfnWorkerCallBackCredentials;
                private Socket m_mainCredentialsSocket;
                private Socket m_workerCredentialsSocket;
                private void StartListeningCrendentials()
                {
                    try
                    {
                        string portStr = "8003";
                        int port_banker = System.Convert.ToInt32(portStr);

                        m_mainCredentialsSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        IPEndPoint ip_credential = new IPEndPoint(IPAddress.Parse(GetIP()), port_banker);

                        m_mainCredentialsSocket.Bind(ip_credential);
                        m_mainCredentialsSocket.Listen(4);
                        m_mainCredentialsSocket.BeginAccept(new AsyncCallback(OnCredentialConnect), null);
                    }
                    catch (Exception e) { throw e; }
                }
                public void OnCredentialConnect(IAsyncResult asyn)
                {
                    try
                    {
                        m_workerCredentialsSocket = m_mainCredentialsSocket.EndAccept(asyn);
                        WaitForCredentials();
                        m_mainCredentialsSocket.BeginAccept(new AsyncCallback(OnCredentialConnect), null);
                    }
                    catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n"); }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                public void WaitForCredentials()
                {
                    try
                    {
                        if (pfnWorkerCallBackCredentials == null)
                        {
                            pfnWorkerCallBackCredentials = new AsyncCallback(OnCredentialsReceived);
                        }
                        SocketPacket theSocPkt = new SocketPacket(m_workerCredentialsSocket);

                        m_workerCredentialsSocket.BeginReceive(theSocPkt.credentialsbuff, 0,
                            theSocPkt.credentialsbuff.Length, SocketFlags.None,
                            pfnWorkerCallBackCredentials, theSocPkt);
                    }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                public void OnCredentialsReceived(IAsyncResult asyn)
                {
                    SocketPacket socketData = (SocketPacket)asyn.AsyncState;
                    try
                    {
                        SendCredentialMessageToClient(socketData);
                        WaitForCredentials();
                    }
                    #region catchBlock
                    catch (ObjectDisposedException)
                    {
                        System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Banker Socket has been closed\n");
                    }
                    catch (SocketException se)
                    {
                        if (se.ErrorCode == 10054) // Error code for Connection reset by peer
                        {
                            //System.Diagnostics.Debugger.Log(0, "1", "Banker Disconnected");

                            // Remove the reference to the worker socket of the closed client
                            // so that this object will get garbage collected
                            //m_workerSocketBankerSendImage = null;

                            //setTextBankerStatus("Banker is currently not connected");
                        }
                        else
                        {
                            //System.Diagnostics.Debugger.Log(0, "1", se.Message);
                        }
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Debugger.Log(0, "1", "\nexception caught");
                        System.Diagnostics.Debugger.Log(0, "1", e.Message);
                        System.Diagnostics.Debugger.Log(0, "1", e.Source);
                        System.Diagnostics.Debugger.Log(0, "1", e.StackTrace);
                    }
                    #endregion catchBlock
                }
                private void SendCredentialMessageToClient(SocketPacket socketData)
                {
                    try
                    {
                        if (m_workerCredentialsSocket != null)
                        {
                            byte[] result;
                            string test = System.Text.Encoding.UTF8.GetString(socketData.credentialsbuff).TrimEnd('\0');;
                            string tcredentials = trusteeUserName +":"+ trusteePasswd;
                            string icredentials = investorUserName +":"+ investorPasswd;

                            if (test.Equals(tcredentials)) { result = Encoding.UTF8.GetBytes("trustee"+":"+credentials.FolderName); }
                            else if (test.Equals(icredentials)) { result = Encoding.UTF8.GetBytes("investor" + ":" + credentials.FolderName); }
                            else { result = Encoding.UTF8.GetBytes("wrong"); }

                            m_workerCredentialsSocket.Send(result);
                        }
                    }
                    catch (Exception e) { throw e; }
                }
            #endregion CredentialSocket
            #region investorGameData
                public AsyncCallback pfnWorkerCallBackInvestorGameData;
                private Socket m_mainGameSocketInvestor;
                private Socket m_workerGameSocketInvestor;
                private void StartListeningInvestorGame()
                {
                    try
                    {
                        string portStr = "8004"; // GetIP();
                        int port_investor = System.Convert.ToInt32(portStr);
                        m_mainGameSocketInvestor = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        IPEndPoint ip_investor = new IPEndPoint(IPAddress.Parse(GetIP()), port_investor);
                        m_mainGameSocketInvestor.Bind(ip_investor);
                        m_mainGameSocketInvestor.Listen(4);
                        m_mainGameSocketInvestor.BeginAccept(new AsyncCallback(OnInvestorGameConnect), null);
                    }
                    catch (Exception e) { throw e; }
                }
                public void OnInvestorGameConnect(IAsyncResult asyn)
                {
                    try
                    {
                        m_workerGameSocketInvestor = m_mainGameSocketInvestor.EndAccept(asyn);
                        WaitForInvestorGameData();
                        m_mainGameSocketInvestor.BeginAccept(new AsyncCallback(OnInvestorGameConnect), null);
                        setTextInvestorStatus("Investor is currently connected");
                    }
                    catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n"); }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                public void WaitForInvestorGameData()
                {
                    try
                    {
                        if (pfnWorkerCallBackInvestorGameData == null){ pfnWorkerCallBackInvestorGameData = new AsyncCallback(OnInvestorGameDataReceived); }
                        SocketPacket theSocPkt = new SocketPacket(m_workerGameSocketInvestor);
                        m_workerGameSocketInvestor.BeginReceive(theSocPkt.gameBuffer, 0, theSocPkt.gameBuffer.Length, SocketFlags.None, pfnWorkerCallBackInvestorGameData, theSocPkt);
                    }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                public void OnInvestorGameDataReceived(IAsyncResult asyn)
                {
                    SocketPacket socketData = (SocketPacket)asyn.AsyncState;
                    try
                    {
                        int val = int.Parse(System.Text.Encoding.UTF8.GetString(socketData.gameBuffer));
                        
                        investorMoney = val;

                        intiateSequence((20-val), val, 1);
                        SendGameMessageToBanker(socketData);
                        WaitForInvestorGameData();
                        setTextGameCommentry("Investor invested " + val.ToString() + " points");

                        updateInfoTextFile("Investor invested : " + val.ToString() + " points");
                        updateInfoTextFile("After business Banker got : " + (3 * val).ToString() + " points");
                    }
                    #region catchBlock
                        catch (ObjectDisposedException)
                        {
                            System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Investor Socket has been closed\n");
                        }
                        catch (SocketException se)
                        {
                            if (se.ErrorCode == 10054) // Error code for Connection reset by peer
                            {
                                m_workerSocketInvestorSendImage = null;

                                setTextInvestorStatus("Investor is currently not connected");
                            }
                            else
                            {
                                System.Diagnostics.Debugger.Log(0, "1", se.Message);
                            }
                        }
                        catch (Exception e)
                        {
                            System.Diagnostics.Debugger.Log(0, "1", "\nexception caught");
                            System.Diagnostics.Debugger.Log(0, "1", e.Message);
                            System.Diagnostics.Debugger.Log(0, "1", e.Source);
                            System.Diagnostics.Debugger.Log(0, "1", e.StackTrace);
                        }
                    #endregion catchBlock
                }
                private void SendGameMessageToBanker(SocketPacket socketData)
                {
                    try
                    {
                        int money_sent = int.Parse(System.Text.Encoding.UTF8.GetString(socketData.gameBuffer));
                        updateGUIInvestor(20, money_sent, 0);
                        updateInvestorSentMoney(money_sent, -1, 20);
                        int moneyForTrustee = 3 * money_sent;
                        updateGUITrustee(moneyForTrustee, 0, 0);

                        Object objData = (Object)(moneyForTrustee.ToString());
                        byte[] byData = System.Text.Encoding.UTF8.GetBytes(objData.ToString());

                        if (m_workerGameSocketBanker != null)
                        {
                            m_workerGameSocketBanker.Send(byData);
                        } 
                    }
                    catch (Exception e)
                    {
                    }
                }
            #endregion investorGameData
            #region investorSendImage
                public AsyncCallback pfnWorkerCallBackInvestorSendImage;
                private Socket m_mainSocketInvestorSendImage;
                private Socket m_workerSocketInvestorSendImage;
                private void StartListeningInvestorSendImage()
                {
                    try
                    {
                        string portStr = "8005"; //GetIP();
                        int port_investor = System.Convert.ToInt32(portStr);
                        m_mainSocketInvestorSendImage = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        IPEndPoint ip_investor = new IPEndPoint(IPAddress.Parse(GetIP()), port_investor);
                        m_mainSocketInvestorSendImage.Bind(ip_investor);
                        m_mainSocketInvestorSendImage.Listen(4);
                        m_mainSocketInvestorSendImage.BeginAccept(new AsyncCallback(OnInvestorSendImageConnect), null);
                    }
                    catch (Exception e) { throw e; }
                }
                public void OnInvestorSendImageConnect(IAsyncResult asyn)
                {
                    try
                    {
                        m_workerSocketInvestorSendImage = m_mainSocketInvestorSendImage.EndAccept(asyn);
                        WaitForInvestorSendImageData();
                        m_mainSocketInvestorSendImage.BeginAccept(new AsyncCallback(OnInvestorSendImageConnect), null);
                        setTextInvestorStatus("Investor is currently connected");
                    }
                    catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n"); }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                public void WaitForInvestorSendImageData()
                {
                    try
                    {
                        if (pfnWorkerCallBackInvestorSendImage == null) { pfnWorkerCallBackInvestorSendImage = new AsyncCallback(OnInvestorSendImageDataReceived); }
                        SocketPacket theSocPkt = new SocketPacket(m_workerSocketInvestorSendImage);
                        m_workerSocketInvestorSendImage.BeginReceive(theSocPkt.dataBuffer, 0, theSocPkt.dataBuffer.Length, SocketFlags.None, pfnWorkerCallBackInvestorSendImage, theSocPkt);
                    }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                public void OnInvestorSendImageDataReceived(IAsyncResult asyn)
                {
                    SocketPacket socketData = (SocketPacket)asyn.AsyncState;
                    try
                    {
                        int iRx = socketData.m_currentSocket.EndReceive(asyn);

                       // setTextGameCommentry(" Got message outside if  : " + iRx.ToString());
                        if (iRx == imageSize1 || iRx == imageSize2)
                        {
                            Image img = byteArrayToImage(socketData.dataBuffer);
                            Image saveimg = cropImage(img);
                            //saveimg.Save(Credentials.folderName + "\\investor\\" + investorImageCounter + ".png");
                            //investorImageCounter++;

                            pictureBox_investor.Image = saveimg;

                            if(clearedToSendImage)
                                SendImageToBanker(socketData);
                        }
                        WaitForInvestorSendImageData();
                    }
                    #region catchBlock
                        catch (ObjectDisposedException)
                        {
                            System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Investor Socket has been closed\n");
                        }
                        catch (SocketException se)
                        {
                            if (se.ErrorCode == 10054) // Error code for Connection reset by peer
                            {
                                m_workerSocketInvestorSendImage = null;

                                setTextInvestorStatus("Investor is currently not connected");
                            }
                            else
                            {
                                System.Diagnostics.Debugger.Log(0, "1", se.Message);
                            }
                        }
                        catch (Exception e)
                        {
                            System.Diagnostics.Debugger.Log(0, "1", "\nexception caught");
                            System.Diagnostics.Debugger.Log(0, "1", e.Message);
                            System.Diagnostics.Debugger.Log(0, "1", e.Source);
                            System.Diagnostics.Debugger.Log(0, "1", e.StackTrace);
                        }
                    #endregion catchBlock
                }
                private void SendImageToBanker(SocketPacket socketData)
                {
                    try { if (m_workerSocketBankerGetImage != null) { m_workerSocketBankerGetImage.Send(socketData.dataBuffer); } }
                    catch (Exception e) { throw e; }
                }
            #endregion investorSendImage
            #region investorGetImage
                public AsyncCallback pfnWorkerCallBackInvestorGetImage;
                private Socket m_mainSocketInvestorGetImage;
                private Socket m_workerSocketInvestorGetImage;
                private void StartListeningInvestorGetImage()
                {
                    try{
                        string portStr = "8006"; // GetIP();
                        int port_investor = System.Convert.ToInt32(portStr);
                        m_mainSocketInvestorGetImage = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        IPEndPoint ip_investor = new IPEndPoint(IPAddress.Parse(GetIP()), port_investor);
                        m_mainSocketInvestorGetImage.Bind(ip_investor);
                        m_mainSocketInvestorGetImage.Listen(4);
                        m_mainSocketInvestorGetImage.BeginAccept(new AsyncCallback(OnInvestorGetImageConnect), null);
                    }
                    catch (Exception e) { throw e; }
                }
                public void OnInvestorGetImageConnect(IAsyncResult asyn)
                {
                    try
                    {
                        m_workerSocketInvestorGetImage = m_mainSocketInvestorGetImage.EndAccept(asyn);
                       // WaitForInvestorGetImageData();
                       // m_mainSocketInvestorGetImage.BeginAccept(new AsyncCallback(OnInvestorGetImageConnect), null);
                       // setTextInvestorStatus("Investor is currently connected");
                    }
                    catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n"); }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
               /* public void WaitForInvestorGetImageData()
                {
                    try
                    {
                        if (pfnWorkerCallBackInvestorSendImage == null)
                        {
                            pfnWorkerCallBackInvestorGetImage = new AsyncCallback(OnInvestorGetImageDataReceived);
                        }
                        SocketPacket theSocPkt = new SocketPacket(m_workerSocketInvestorGetImage);

                        m_workerSocketInvestorGetImage.BeginReceive(theSocPkt.dataBuffer, 0,
                            theSocPkt.dataBuffer.Length, SocketFlags.None,
                            pfnWorkerCallBackInvestorGetImage, theSocPkt);
                    }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
                public void OnInvestorGetImageDataReceived(IAsyncResult asyn)
                {
                    SocketPacket socketData = (SocketPacket)asyn.AsyncState;
                    try
                    {
                        int iRx = socketData.m_currentSocket.EndReceive(asyn);
                        if (iRx == 800054)
                        {
                            //investorPicture.Image = byteArrayToImage(socketData.dataBuffer);
                            //SendMessageToBanker(socketData);
                        }
                        // Continue the waiting for data on the Socket
                        WaitForInvestorGetImageData();

                    }
                    #region catchBlock
                        catch (ObjectDisposedException)
                        {
                            System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Investor Socket has been closed\n");
                        }
                        catch (SocketException se)
                        {
                            if (se.ErrorCode == 10054) // Error code for Connection reset by peer
                            {
                                m_workerSocketInvestorSendImage = null;

                                setTextInvestorStatus("Investor is currently not connected");
                            }
                            else
                            {
                                System.Diagnostics.Debugger.Log(0, "1", se.Message);
                            }
                        }
                        catch (Exception e)
                        {
                            System.Diagnostics.Debugger.Log(0, "1", "\nexception caught");
                            System.Diagnostics.Debugger.Log(0, "1", e.Message);
                            System.Diagnostics.Debugger.Log(0, "1", e.Source);
                            System.Diagnostics.Debugger.Log(0, "1", e.StackTrace);
                        }
                    #endregion catchBlock
                }
                private void SendMessageToBanker(SocketPacket socketData)
                {
                    try { if (m_workerSocketBankerSendImage != null) { m_workerSocketBankerSendImage.Send(socketData.dataBuffer); } }
                    catch (Exception e) { throw; }
                } */
            #endregion investorGetImage
        #endregion socket_operations

        public Image byteArrayToImage(byte[] byteArrayIn)
        {
            MemoryStream ms = new MemoryStream(byteArrayIn);
            Image returnImage = Image.FromStream(ms);
            return returnImage;
        }
        private void startServer()
        {
            //check all the needs then start listening
            try
            {
                StartListeningTrusteeGetImage();
                StartListeningTrusteeSendImage();
                StartListeningTrusteeGame();
                StartListeningTrusteeStats();

                StartListeningCrendentials();

                StartListeningInvestorGetImage();
                StartListeningInvestorSendImage();
                StartListeningInvestorGame();
                StartListeningInvStats();

            }
            catch (SocketException se)
            {
                MessageBox.Show(se.Message);
            }
        }        

        #region delegate_messageToServerClientConnect
                //delegate method for setting up banker status
                delegate void BankerStatusDelegate(string status);
                public void setTextBankerStatus(String status)
                {
                    if (label_trusteeconnection.InvokeRequired)
                    {
                        // this is worker thread
                        BankerStatusDelegate del = new BankerStatusDelegate(setTextBankerStatus);
                        label_trusteeconnection.Invoke(del, new object[] { status });
                    }
                    else
                    {
                        // this is UI thread
                        label_trusteeconnection.Text = status;
                    }
                }
                //delegate method for setting up investor status
                delegate void InvestorStatusDelegate(string status);
                public void setTextInvestorStatus(String status)
                {
                    if (label_investorconnection.InvokeRequired)
                    {
                        // this is worker thread
                        InvestorStatusDelegate del = new InvestorStatusDelegate(setTextInvestorStatus);
                        label_investorconnection.Invoke(del, new object[] { status });
                    }
                    else
                    {
                        // this is UI thread
                        label_investorconnection.Text = status;
                    }
                }

                delegate void setTextGameCommentryDelegate(string serverData);
                public void setTextGameCommentry(String serverData)
                {
                    if (richTextBox1.InvokeRequired)
                    {
                        // this is worker thread
                        setTextGameCommentryDelegate del = new setTextGameCommentryDelegate(setTextGameCommentry);
                        richTextBox1.Invoke(del, new object[] { serverData });
                    }
                    else
                    {
                        // this is UI thread
                        richTextBox1.Text = richTextBox1.Text + "\n" + serverData;
                    }

                }
        #endregion delegate_messageToServerClientConnect        
        #region stop_server
            void CloseSockets()
            {
                if (m_mainSocketBankerGetImage != null) { m_mainSocketBankerGetImage.Close(); }
                if (m_workerSocketBankerGetImage != null) { m_workerSocketBankerGetImage.Close(); }

                if (m_mainSocketBankerSendImage != null){m_mainSocketBankerSendImage.Close();}
                if (m_workerSocketBankerSendImage != null) { m_workerSocketBankerSendImage.Close(); }

                if (m_mainGameSocketBanker != null) { m_mainGameSocketBanker.Close(); }
                if (m_workerGameSocketBanker != null) { m_workerGameSocketBanker.Close(); }

                if (m_mainSocketInvestorGetImage != null) { m_mainSocketInvestorGetImage.Close(); }
                if (m_workerSocketInvestorGetImage != null){m_workerSocketInvestorGetImage.Close();}

                if (m_mainSocketInvestorSendImage != null){m_mainSocketInvestorSendImage.Close();}
                if (m_workerSocketInvestorSendImage != null) { m_workerSocketInvestorSendImage.Close(); }

                if (m_mainGameSocketInvestor != null) { m_mainGameSocketInvestor.Close(); }
                if (m_workerGameSocketInvestor != null) { m_workerGameSocketInvestor.Close(); }

                if (m_workerInvStats != null) { m_workerInvStats.Close(); }
                if (m_workerTrusteeStats != null) { m_workerTrusteeStats.Close(); }
                if (m_mainInvStats != null) { m_mainInvStats.Close(); }
                if (m_mainTrusteeStats != null) { m_mainTrusteeStats.Close(); }
                if (m_mainCredentialsSocket != null) { m_mainCredentialsSocket.Close(); }
                if (m_workerCredentialsSocket != null) { m_workerCredentialsSocket.Close(); };
                count = 0;

                //close the file too
                if(tw != null)
                    tw.Close();
            }
        #endregion stop_server

        private void startTimer1(int milisecs)
        {
            MyTimer1 = new System.Windows.Forms.Timer();
            MyTimer1.Interval = (milisecs);
            MyTimer1.Tick += new EventHandler(MyTimer_Tick1);
            MyTimer1.Start();
        }
        private void MyTimer_Tick1(object sender, EventArgs e)
        {
            if (playerTypeInvorRepay == 1)
            {
                SendStatMessageToInvestor(2, playerKept, playerGave, 1);
                SendStatMessageToTrustee(2, playerKept, playerGave, 1);
            }

            if (playerTypeInvorRepay == 2)
            {
                SendStatMessageToTrustee(2, playerKept, playerGave, 2); // send message to clients
                SendStatMessageToInvestor(2, playerKept, playerGave, 2); // send message to clients
            }
            MyTimer1.Stop();
            MyTimer1 = null;            
        }

        private void startTimer2(int milisecs)
        {
            MyTimer2 = new System.Windows.Forms.Timer();
            MyTimer2.Interval = (milisecs);
            MyTimer2.Tick += new EventHandler(MyTimer_Tick2);
            MyTimer2.Start();
        }
        private void MyTimer_Tick2(object sender, EventArgs e)
        {
            MyTimer2.Stop();
            MyTimer2 = null;

            if (playerTypeInvorRepay == 1)
            {
                SendStatMessageToTrustee(1, 0, 0, 2);
                SendStatMessageToInvestor(1, 0, 0, 2);
            }

            if (playerTypeInvorRepay == 2)
            {
                SendStatMessageToInvestor(3, (20 - ((playerKept + playerGave) / 3)), playerKept, 0);//totals
                SendStatMessageToTrustee(3, (20 - ((playerKept + playerGave) / 3)), playerKept, 0);//totals
            }
        }

        private void startTimer3(int milisecs)
        {
            MyTimer3 = new System.Windows.Forms.Timer();
            MyTimer3.Interval = (milisecs);
            MyTimer3.Tick += new EventHandler(MyTimer_Tick3);
            MyTimer3.Start();
        }
        private void MyTimer_Tick3(object sender, EventArgs e)
        {
            MyTimer3.Stop();
            MyTimer3 = null;
            if (playerTypeInvorRepay == 1)
            {
                //do nothing
            }

            if (playerTypeInvorRepay == 2)
            {
                SendStatMessageToTrustee(1, 0, 0, 1);
                SendStatMessageToInvestor(1, 0, 0, 1);
                resetDataAndRoundNumber();
            }
        }

        public delegate void sendStatToClientDelegate();
        public void sendStatToClient()
        {
            this.Invoke(new sendStatToClientDelegate(sendStat2Client));
        }
        public void sendStat2Client()
        {
            Thread.Sleep(4000);
            if (playerTypeInvorRepay == 1)
            {
                SendStatMessageToInvestor(2, playerKept, playerGave, 1);
                SendStatMessageToTrustee(2, playerKept, playerGave, 1);
            }

            if (playerTypeInvorRepay == 2)
            {
                SendStatMessageToTrustee(2, playerKept, playerGave, 2);
                SendStatMessageToInvestor(2, playerKept, playerGave, 2);
            }
            Thread.Sleep(18000);
            if (playerTypeInvorRepay == 1)
            {
                SendStatMessageToTrustee(1, 0, 0, 2);
                SendStatMessageToInvestor(1, 0, 0, 2);
            }

            if (playerTypeInvorRepay == 2)
            {
                SendStatMessageToInvestor(3, (20 + playerGave - ((playerKept + playerGave) / 3)), playerKept, 0);//totals
                SendStatMessageToTrustee(3, (20 + playerGave - ((playerKept + playerGave) / 3)), playerKept, 0);//totals
            }

            Thread.Sleep(12000);
            if (playerTypeInvorRepay == 1)
            {
                //do nothing
            }

            if (playerTypeInvorRepay == 2)
            {
                bool shouldGameContinue = resetDataAndRoundNumber();
                if (shouldGameContinue)
                {
                    SendStatMessageToTrustee(1, 0, 0, 1);
                    SendStatMessageToInvestor(1, 0, 0, 1);
                }
                else
                {
                    SendStatMessageToInvestor(-2, int.Parse(textBox_investorTotalProfit.Text),
                      int.Parse(textBox_trusteeTotalProfit.Text), -1);
                    SendStatMessageToTrustee(-2, int.Parse(textBox_investorTotalProfit.Text),
                      int.Parse(textBox_trusteeTotalProfit.Text), - 1);

                    Thread.Sleep(12000);

                    SendStatMessageToInvestor(-1, -1, -1, -1);
                    SendStatMessageToTrustee(-1, -1, -1, -1);                      
                }

            }

        }

        private int playerKept;
        private int playerGave;
        private int playerTypeInvorRepay;

        private void intiateSequence(int kept, int gave, int playerType)
        {
            // type 1 -- message to show cue
            // type 2 -- message to show stats
            // type 3 -- message to show total
            // player 1 -- investor
            // player 2 -- trustee

            playerKept = kept;
            playerGave = gave;
            playerTypeInvorRepay = playerType;
            if (count == 2)
            {
                Thread t = new Thread(sendStat2Client);
                t.Start();
            }
        }

        private bool resetDataAndRoundNumber()
        {
            int roundNo = int.Parse(textBox_roundNumber.Text);

            if (roundNo < FINALROUNDNUMBER)
            {
                setRoundNumber(roundNo + 1);
                updateGUIInvestor(20, 0, 0);
                updateGUITrustee(0, 0, 0);
                return true;
            }
            else
            {
                return false;
            }
            //after each round we will reset all the data associated with each round and also update the round numbers
        }

        public delegate void updatePLafterRound();
        public void updateprofitLossAftereachRound()
        {
            this.Invoke(new updatePLafterRound(updateProfitLoss));
        }
        public void updateProfitLoss()
        {
            investorMoney = 0;
            textBox_trusteeRoundProfit.Text = "0";
            textBox_investorRoundProfit.Text = "0";
        }

        #region stats
            private int count = 0;

            public delegate void delUpdateCounter();
            private void updateCount()
            {
                this.Invoke(new delUpdateCounter(updateC));
            }
            public void updateC()
            {
                if(count < 2)
                    count++;
            }

            public delegate void delSendCueFirstime(int connectionCode);
            public void sendCue(int connectionCode)
            {
                this.Invoke(new delSendCueFirstime(sendCueFirst), new Object[]{connectionCode});
            }
            public void sendCueFirst(int connectionCode)
            {
                Thread thread = new Thread(Execute);
                thread.Start();
            }

            protected void Execute()
            {
                Thread.Sleep(4000);
                clearedToSendImage = true;
                textBox_roundNumber.Text = "1";
                updateInfoTextFile("Round Number 1");
                Thread.Sleep(4000);
                SendStatMessageToTrustee(1, 0, 0, 1);
                SendStatMessageToInvestor(1, 0, 0, 1);
            }

            public int getC()
            {
                return count;
            }
            #region statInvestor
                public AsyncCallback pfnWorkerCallBackInvStats;
                private Socket m_mainInvStats;
                private Socket m_workerInvStats;

                private void StartListeningInvStats()
                {
                    try
                    {
                        string portStr = "8007";
                        int port_stat = System.Convert.ToInt32(portStr);
                        m_mainInvStats = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        IPEndPoint ip_stat = new IPEndPoint(IPAddress.Parse(GetIP()), port_stat);
                        m_mainInvStats.Bind(ip_stat);
                        m_mainInvStats.Listen(4);
                        m_mainInvStats.BeginAccept(new AsyncCallback(OnInvStatsConnect), null);
                    }
                    catch (Exception e) { throw e; }
                }
                public void OnInvStatsConnect(IAsyncResult asyn)
                {
                    try
                    {
                        m_workerInvStats = m_mainInvStats.EndAccept(asyn);
                        updateCount();
                        if (getC() == 2)
                        {
                            sendCue(investorConnectionCode);
                        }
                        m_mainInvStats.BeginAccept(new AsyncCallback(OnInvStatsConnect), null);
                    }
                    catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n"); }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }
        
                //1 -> investor
                //2 -> trustee
                private void SendStatMessageToInvestor(int type, int kept, int gave, int player)
                {            
                    string sent = type.ToString() + ":" + kept.ToString() + ":" + gave.ToString() + ":" + player.ToString();
                    byte[] messg = System.Text.Encoding.UTF8.GetBytes(sent.ToCharArray());

                    try
                    { 
                        if (m_workerInvStats != null)  {  m_workerInvStats.Send(messg);  } 
                    }
                    catch (Exception e) { throw e; }
                }
            #endregion statInvestor
            #region statTrustee
                public AsyncCallback pfnWorkerCallBackTrusteeStats;
                private Socket m_mainTrusteeStats;
                private Socket m_workerTrusteeStats;

                private void StartListeningTrusteeStats()
                {
                    try
                    {
                        string portStr = "8008";
                        int port_stat = System.Convert.ToInt32(portStr);
                        m_mainTrusteeStats = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        IPEndPoint ip_stat = new IPEndPoint(IPAddress.Parse(GetIP()), port_stat);
                        m_mainTrusteeStats.Bind(ip_stat);
                        m_mainTrusteeStats.Listen(4);
                        m_mainTrusteeStats.BeginAccept(new AsyncCallback(OnTrusteeStatsConnect), null);
                    }
                    catch (Exception e) { throw e; }
                }
                public void OnTrusteeStatsConnect(IAsyncResult asyn)
                {
                    try
                    {
                        m_workerTrusteeStats = m_mainTrusteeStats.EndAccept(asyn);
                        updateCount();
                        if (getC() == 2)
                        {
                            sendCue(trusteeConnectionCode);
                        }
                        m_mainTrusteeStats.BeginAccept(new AsyncCallback(OnTrusteeStatsConnect), null);
                    }
                    catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n"); }
                    catch (SocketException se) { System.Diagnostics.Debugger.Log(0, "1", se.Message); }
                }

                //1 -> investor
                //2 -> trustee
                private void SendStatMessageToTrustee(int type, int kept, int gave, int player)
                {
                    string sent = type.ToString() + ":" + kept.ToString() + ":" + gave.ToString() + ":" + player.ToString();
                    byte[] messg = System.Text.Encoding.UTF8.GetBytes(sent.ToCharArray());

                    try
                    {
                        if (m_workerTrusteeStats != null) { m_workerTrusteeStats.Send(messg); }
                    }
                    catch (Exception e) { throw e; }
                }
            #endregion statTrustee
        #endregion stats
    }
}
 